home *** CD-ROM | disk | FTP | other *** search
- /************************************************************
- * Program: CMENU Menu Compiler
- * Module: cmenu1.c
- * Menu Compiler:
- * Main and Utility Functions
- * Written by: Leor Zolman, 7/91
- ************************************************************/
-
- #define MASTER
- #include "cmenu.h"
- #include "ccmenu.h"
-
- #include <string.h>
-
- #if __STDC__
- # include <stdarg.h>
- #else
- # include <varargs.h>
- #endif
-
- int main(argc,argv)
- int argc;
- char **argv;
- {
- register i;
-
- printf("CMENU Menu Compiler v%s\n", VERSION);
- if (argc < 2)
- {
- puts("usage: cmenu <menu-source-file(s)>\n");
- return 0;
- }
-
- for (i = 1; i < argc; i++)
- if (dofile(argv[i]) == ERROR) /* process source files */
- return 1;
- return 0;
- }
-
- /************************************************************
- * dofile():
- * Process a single .mnu source file
- ************************************************************/
-
- int dofile(name)
- char *name;
- {
- register i;
- char *cp;
-
- if ((cp = strstr(name, ".mnu")) ||
- (cp = strstr(name, ".MNU")))
- *cp = '\0';
-
- strcpy(src_name, name);
- strcat(src_name, ".mnu");
- strcpy(obj_name, name);
-
- if ((fp = fopen(src_name, "r")) == NULL)
- return fprintf(stderr, "Can't open %s\n", src_name);
-
- n_menus = 0;
- lineno = 1;
- in_menu = FALSE;
- fatal = FALSE;
-
- /* Main processing loop. Read a token and process it,
- * until end of file is reached:
- */
-
- while ((token = gettok(fp)) != T_EOF)
- {
- if (!in_menu && token != T_MENU)
- {
- error("Each menu must begin with the Menu keyword");
- break;
- }
- if ((*keywords[token].t_func)() == ERROR)
- if (fatal) /* If fatal error, exit loop */
- break;
- }
-
- fclose(fp);
-
- if (!n_menus)
- return error("No menus defined");
-
- if (in_menu)
- {
- if (n_items)
- itemcheck();
- error("Menu definition missing \"Endmenu\" statement");
- }
-
- for (i = 0; i < n_menus; i++) /* check for undefined */
- if (!MInfo[i].Processed) /* "lmenu" references */
- {
- printf("Local Menu \"%s\" is undefined.\n",
- MInfo[i].Name);
- err_flag = TRUE;
- }
-
- if (err_flag)
- return ERROR;
-
- if (write_file() == ERROR)
- return ERROR;
- return OK;
- }
-
-
- /************************************************************
- * create_menu():
- * Construct a new menu information structure and
- * return it (by value).
- * Set fatal to TRUE if can't create.
- ************************************************************/
-
- MINFO create_menu(name)
- char *name;
- {
- MINFO mi;
-
- if (n_menus == MAX_MENUS)
- fatalerr("Maximum # of menus (%d) exceeded", MAX_MENUS);
- else
- {
- strcpy(mi.Name, name);
- mi.Processed = FALSE;
- }
- return mi;
- }
-
-
- /************************************************************
- * find_menu():
- * Search the Menu Info table for a named local menu.
- * If found:
- * Return a pointer to the entry if found, and set
- * global variable menu_num to the menu's index
- * else:
- * return NULL
- ************************************************************/
-
- MINFO *find_menu(name)
- char *name;
- {
- int i;
-
- for (i = 0; i < n_menus; i++)
- if (!strcmp(MInfo[i].Name, name))
- {
- menu_num = i;
- return &MInfo[i];
- }
- return NULL;
- }
-
-
- /************************************************************
- * create_item(): Allocate space for Item Info structure,
- * Initialize it and return a pointer to the structure
- * Return NULL if there was a creation error.
- ************************************************************/
-
- IINFO *create_item(name)
- char *name;
- {
- IINFO *IIp;
- ITEM *Ip;
-
- if (n_items == MAX_ITEMS)
- {
- fatalerr("Max. # of items (%d) exceeded", MAX_ITEMS);
- return NULL;
- }
-
- if ((IIp = (IINFO *) malloc(sizeof(IINFO))) == NULL)
- {
- fatalerr("Out of memory");
- return NULL;
- }
-
- strcpy(IIp->Name, name);
- Ip = &IIp->Item;
- Ip->acttyp = ACT_NONE;
- Ip->pre_clear = Ip->post_clear = Ip->prompt = DEFAULT;
- Ip->nextcode = DEFAULT;
- Ip->nextitem = Ip->lmenunum = 0;
- *Ip->text = *Ip->path = *Ip->action = *Ip->help = '\0';
- return IIp;
- }
-
-
- /************************************************************
- * find_item():
- * Search the Item Info table for a named item in the
- * currently active menu definition.
- * If item name found:
- * Set item_num to the index value of the Item,
- * Return a pointer to the entry
- * else:
- * return NULL
- ************************************************************/
-
- IINFO *find_item(name)
- char *name;
- {
- int i;
-
- for (i = 0; i < n_items; i++)
- if (!strcmp(MIp->Items[i]->Name, name))
- {
- item_num = i;
- return MIp->Items[i];
- }
- return NULL;
- }
-
-
- /************************************************************
- * itemcheck():
- * Check the currently active item to make sure
- * both a Text and an Action clause have been
- * explicitly given.
- ************************************************************/
-
- Void itemcheck()
- {
- if (!*Ip->text)
- error("No TEXT clause found for current item");
- if (Ip->acttyp == ACT_NONE)
- error("No ACTION clause found for current item");
- }
-
-
- /************************************************************
- * write_file():
- * Write menu object file to disk, ready for
- * execution via rmenu.
- * Menu object file format:
- * --------------------------------
- * <count> (integer count of # of menus in file)
- * MENU 1 (MENU structure for 1st Menu)
- * ITEM 1
- * ITEM 2
- * ...
- * ITEM n_items
- * MENU 2 (MENU structure for 2nd Menu)
- * ...
- * .
- * .
- * .
- * MENU <count> (MENU structure for final Menu)
- * ...
- * --------------------------------
- *
- ************************************************************/
-
- int write_file()
- {
- int i,j;
-
- strcat(obj_name, ".mnc");
-
- if ((fp = fopen(obj_name, "wb")) == NULL)
- {
- fprintf(stderr,
- "Cannot open %s for writing.\n", obj_name);
- return ERROR;
- }
-
- if (fwrite((Void *)&n_menus, sizeof n_menus, 1, fp) != 1)
- {
- fprintf(stderr,
- "Error writing menu count to %s\n", obj_name);
- return ERROR;
- }
-
- for (i = 0; i < n_menus; i++)
- {
- Mp = &MInfo[i].Menu;
- if (fwrite((Void *) Mp, sizeof (MENU), 1, fp) != 1)
- {
- fprintf(stderr,
- "Error writing to %s\n", obj_name);
- return ERROR;
- }
-
- for (j = 0; j < Mp->nitems; j++)
- {
- if (fwrite((Void *) &MInfo[i].Items[j]->Item,
- sizeof (ITEM), 1, fp) != 1)
- {
- fprintf(stderr,
- "Error writing to %s\n", obj_name);
- return ERROR;
- }
- free(MInfo[i].Items[j]);
- }
- }
- printf("Menu object file %s written.\n", obj_name);
- return OK;
- }
-
-
- /************************************************************
- * warning():
- * Display a warning message, preceded by source
- * file name and line number, supporting format
- * conversions.
- ************************************************************/
-
- #if __STDC__ /* ANSI variable-#-of-args method: */
- int warning(char *fmt, ...)
- {
- va_list arglist;
- va_start(arglist, fmt);
-
- #else /* old "varargs" method: */
- int warning(fmt, va_alist)
- char *fmt;
- va_dcl
- {
- va_list arglist;
- va_start(arglist);
- #endif
- /* the rest is the same, ANSI or varargs: */
-
- fprintf(stderr, "%s (%d): ", src_name, lineno);
- vfprintf(stderr, fmt, arglist);
- va_end(arglist);
- fprintf(stderr, "\n");
- return OK;
- }
-
-
- /************************************************************
- * error():
- * Display an error message, preceded by source
- * file name and line number, supporting format
- * conversions.
- ************************************************************/
-
- #if __STDC__ /* ANSI variable-#-of-args method: */
- int error(char *fmt, ...)
- {
- va_list arglist;
- va_start(arglist, fmt);
-
- #else /* old "varargs" method: */
- int error(fmt, va_alist)
- char *fmt;
- va_dcl
- {
- va_list arglist;
- va_start(arglist);
- #endif
-
- /* the rest is the same, ANSI or varargs: */
-
- fprintf(stderr, "%s (%d): ", src_name, lineno);
- vfprintf(stderr, fmt, arglist);
- va_end(arglist);
- fprintf(stderr, "\n");
- err_flag = TRUE;
- return ERROR;
- }
-
-
- /************************************************************
- * fatalerr():
- * Like error, except global flag "fatal" is set.
- ************************************************************/
-
- #if __STDC__ /* start function the ANSI way... */
- int fatalerr(char *fmt, ...)
- {
- va_list arglist;
- va_start(arglist, fmt);
- #else /* or the old "varargs" way... */
- int fatalerr(fmt, va_alist)
- char *fmt;
- va_dcl
- {
- va_list arglist;
- va_start(arglist);
- #endif
-
- error(fmt, arglist); /* the rest is same, ANSI or varargs */
- va_end(arglist);
- fatal = TRUE;
- return ERROR;
- }
-
-
- /************************************************************
- * matchkey():
- * Test if given string is a reserved word. Return the token
- * value of the matching token if so; else return NULL.
- ************************************************************/
-
- int matchkey(str)
- char *str;
- {
- char str2[MAX_CMD], *cp;
- int i;
-
- strcpy(str2, str);
- for (cp = str2; *cp; cp++)
- *cp = tolower(*cp);
-
- for (i = 0; i < (int) N_KEYWORDS; i++)
- if (!strcmp(keywords[i].keyword, str2))
- return i;
-
- return NULL;
- }
-
-
- #ifdef NEEDSTR
- /*
- * Search for first occurence of substring s2 in s1:
- * (provided for Xenix only; this function is in
- * most modern standard distribution libraries)
- */
-
- char *strstr(s1, s2)
- char *s1, *s2;
- {
- int i, j, nposs;
- int len1 = strlen(s1);
-
- int len2 = strlen(s2);
- char *p1;
-
-
- if (len1 < len2)
- return NULL;
-
- nposs = len1 - len2;
-
- for (i = 0; i <= nposs; i++)
- {
- for (j = 0, p1 = &s1[i]; j < len2; j++)
- if (*p1++ != s2[j])
- break;
- if (j == len2)
- return &s1[i];
- }
- return NULL;
- }
- #endif
-